package it.polito.connectedcar;

import it.polito.connectedcar.network.EntityType;
import it.polito.connectedcar.network.InductiveLoopMessage;
import it.polito.connectedcar.network.Message;
import it.polito.connectedcar.network.Neighbor;
import it.polito.connectedcar.network.NeighborhoodMessage;
import it.polito.connectedcar.network.TargetEntityDelegate;
import it.polito.connectedcar.network.TrafficLightMessage;
import it.polito.connectedcar.network.VehicleMessage;
import it.polito.connectedcar.util.LatLng;

import java.util.ArrayList;
import java.util.List;

public class ConnectedVehicle extends BaseConnectedObject implements VehicleUpdateDelegate, TargetEntityDelegate{

	private static final long TIME_DIFF_THRESHOLD = 0;
	private SourceVehicle vehicle;
	private List<Zone> connectedZones;
	private LatLng lastPosition;
	private float lastSpeed;
	
	public ConnectedVehicle(SourceVehicle vehicle) throws Exception {
		this.vehicle=vehicle;
		this.vehicle.setVehicleUpdateDelegate(this);
		
		connectedZones = new ArrayList<Zone>();
	}
	
	public void onStart() {
		
		networkConnector.getMessageProcessor().registerDelegateForEntity(this, EntityType.TRAFFIC_LIGHT);
		networkConnector.getMessageProcessor().registerDelegateForEntity(this, EntityType.VEHICLE);
		networkConnector.getMessageProcessor().registerDelegateForEntity(this, EntityType.INDUCTIVE_LOOP);
		networkConnector.getMessageProcessor().registerDelegateForEntity(this, EntityType.NEIGHBORHOOD);

	}
	
	@Override
	public void onSpeedChange(float speed) {
		lastSpeed = speed;
		
	}
	@Override
	public void onLocationChange(double latitude, double longitude) {
		if(lastPosition==null)
			lastPosition = new LatLng(latitude, longitude);
		else
			lastPosition.update(latitude, longitude);
		VehicleMessage m = new VehicleMessage();
		m.putPosition(lastPosition);
		m.putSpeed(lastSpeed);
		
		
		
		/*
		 * What has to be sent is the direction of the vehicle along with the speed and the location expressed in geographical coordinates 
		 */
		
		for(Zone z :connectedZones)
		{
			for(Neighbor n : z.getNeighbors().values())
			{
				networkConnector.sendMessageTo(m, n.getAddress(), n.getPort());
			}
		}
		/*send the new position together with the new speed to all neighbors vehicles*/
		
		/*send the updated position to the TCC so that he can forward it to the near vehicles*/
		networkConnector.sendMessageTo(m, TCCAddress, TCCPort);
	}

	@Override
	public void processMessage(Message message, EntityType type) {
		switch(type)
		{
			case INDUCTIVE_LOOP:
				processInductiveLoopMessage((InductiveLoopMessage) message);
			break;
			case TRAFFIC_LIGHT:
				processTrafficLightMessage((TrafficLightMessage) message);
			break;
			case VEHICLE:
				processVehicleMessage((VehicleMessage)message);
			break;
			case NEIGHBORHOOD:
				processNeighborhoodMessage((NeighborhoodMessage)message);
			break;
			default:
				System.out.println("unrecognized Type");
			break;
		}
		
	}
	
	/**
	 * check inside whether there is a neighbour to be added or to be removed.
	 * check also about new session key assignment
	 * @param message
	 */
	private void processNeighborhoodMessage(NeighborhoodMessage message)
	{
		
	}

	private void processTrafficLightMessage(TrafficLightMessage message)
	{
		
	}
	private void processInductiveLoopMessage(InductiveLoopMessage message)
	{
		
	}
	private void processVehicleMessage(VehicleMessage message)
	{
		
	}
	
}
